from smbus import SMBus


class RadioStatus:
    RADIO_PLAY = 0
    RADIO_SEARCHING_UP = 1
    RADIO_SEARCHING_DOWN = 2
    RADIO_PAUSE = 3

    BAD_FREQUENCY = -1


class Tea5767:

    UPPER_BAND_LIMIT = 108
    LOWER_BAND_LIMIT = 87.5
    BAND_STEP = 0.1

    def __init__(self):
        # i2c
        self.__i2c = SMBus(1)
        self.__address = 0x60
        self.__crystalOscillatorFrequency = 32768
        self.__dataSize = 5

        # radio parameter
        # self.mute = 0
        # just for logistic usage, not chip mode
        # self.searchMode = 0
        self.frequency = Tea5767.LOWER_BAND_LIMIT

    def __encode14bits_frequency(self, frequency):
        frequency14bits = int(4 * (frequency * 1000000+225000) / self.__crystalOscillatorFrequency)
        return [int(frequency14bits >> 8), int(frequency14bits & 0xff)]

    def __decode14bit_frequency(self, upper, lower):
        # return round((float(round(int(((int(upper) << 8)+int(lower)) * self.__crystalOscillatorFrequency / 4 - 22500) / 100000) / 10) - .2) * 10) / 10
        frequency14bits = int(int(upper << 8) + int(lower))
        frequency = round(frequency14bits * self.__crystalOscillatorFrequency / 4 - 225000) / 1000000
        return round(frequency, 1)

    def __set_data(self, freq, data1, data3, data4=0b00010000, data5=0x00):
        upper, lower = self.__encode14bits_frequency(freq)
        data = [0x00, lower, data3, data4, data5]
        data[0] = ((data1 & 0b11000000) | upper)
        self.__i2c.write_i2c_block_data(self.__address, data[0], data[1:])

    def set_mute(self, muted):
        self.__set_data(self.frequency, data1=0b10000000 if muted else 0x00, data3=0b00010000)

    def set_frequency(self, frequency):
        """
        :param frequency: valid range of [87.5, 108]
        """

        if frequency < Tea5767.LOWER_BAND_LIMIT or frequency > Tea5767.UPPER_BAND_LIMIT:
            return RadioStatus.BAD_FREQUENCY
        self.frequency = frequency
        self.__set_data(self.frequency, data1=0x00, data3=0b00010000)

    def seek_up(self, freq):
        self.__set_data(freq, data1=0b01000000, data3=0b11010000)

    def seek_down(self, freq):
        self.__set_data(freq, data1=0b01000000, data3=0b01010000)

if __name__ == "__main__":
    radio = Tea5767()
    # radio.set_frequency(87.5)
    radio.seek_down(87.5)